#!/usr/bin/env bash
set -e
set -u
set -o pipefail

rname=origin
rpath=
build=stable
mode=test
UserAt=
ingredients=
hardmake=./
configfile=

# TODO: Finish the help.
print_help() {
    echo "script usage: $(basename $0)" &&\
        echo "              [-a add remotes mode]" &&\
        echo "              [-b set the build for checkout]" &&\
        echo "              [-c checkout a build; default stable]" &&\
        echo "              [-d clone dependencies from the remote]" &&\
        echo "              [-f set the config file]" &&\
        echo "              [-h help]" &&\
        echo "              [-i set the projects to use from the config file]" &&\
        echo "              [-p set the relative path to hardmake.sh]" &&\
        echo "              [-r set name of the remote to use]" &&\
        echo "              [-R set generic path for the set of remotes to use]" &&\
        echo "              [-s use ssh instead of https - WARNING: planned removal]" &&\
        echo "              [-t run the test]" &&\
        echo "              [-u set the username for https]"
}

while getopts 'ab:cdf:hi:p:r:R:stu:' OPTION; do
    case "$OPTION" in
        a)
            mode=remotes
            #echo "mode: $mode"
            ;;
        b)
            build="$OPTARG"
            #echo "build: $build"
            ;;
        c)
            mode=checkout
            #echo "mode: $mode"
            ;;
        d)
            mode=clone
            #echo "mode: $mode"
            ;;
        f)
            configfile="$OPTARG"
            #echo "configfile: $configfile"
            ;;
        h)
            print_help >&2
            exit 0
            ;;
        i)
            ingredients="$OPTARG"
            #echo "ingredients: $ingredients"
            ;;
        p)
            hardmake="$OPTARG"
            ;;
        r)
            rname="$OPTARG"
            #echo "rname: $rname"
            ;;
        R)
            rpath="$OPTARG"
            #echo "rpath: $rpath"
            ;;
        s)
            rname=ssh
            #echo "using ssh instead of https"
            ;;
        t)
            mode=test
            #echo "mode: $mode"
            ;;
        u)
            UserAt="$OPTARG"
            #echo "userAt: $UserAt"
            ;;
        ?)  print_help >&2; exit 1;;
    esac
done
shift "$(($OPTIND -1))"

add_user_to_remote() {
    local remote=$1
    local UserAt=${2:-""}
    
    if [ ! "$UserAt" = "" ] ; then
        local remoteMod="${remote/https\:\/\//https\:\/\/$UserAt@}"
        echo $remoteMod
    else
        echo $remote
    fi
}

add_remotes() {
    create_variables ${configfile} ''
    
    local ingredients=( "$@" )
    for current in "${ingredients[@]}"
    do
        # echo cloning $current
        local path=$(eval echo "\$${current}_path")
        #NOTE: Clever, but too noisy on misses.
        # local remotePath=${rpath:-$remoteInit}${rpath+$remoteIndex}
        if [ "$path" = "" ]; then 
            echo ";; no path found for $current"
        elif [ "$rname" = "" ] ; then 
            echo ";; no rname found"
        elif [ ! -d ./$path ]; then
            echo ";; no repo found for $path"
        elif [ ! "$rpath" = "" ] ; then
            # Add a remote from the UI, given the rpath and rname
            local remoteOrigin=$(eval echo "\$${current}_remote_origin")
            local remoteIndex=${remoteOrigin##*/}
            local remoteFoo=${rpath}${remoteIndex}
            local remoteMod=$(add_user_to_remote $remoteFoo $UserAt)
            git --git-dir ${path}.git remote add ${rname} ${remoteMod}
        else
            # Add a remote from the config file, given the rname
            local remotePath=$(eval echo "\$${current}_remote_${rname}")
            local remoteMod=$(add_user_to_remote $remotePath $UserAt)
            git --git-dir ${path}.git remote add ${rname} ${remoteMod}
        fi
    done
    #echo done
}

clone_dependencies() {
    create_variables ${configfile} ''
    
    local ingredients=( "$@" )
    for current in "${ingredients[@]}"
    do
        # echo cloning $current
        local path=$(eval echo "\$${current}_path")
        local remotePath=$(eval echo "\$${current}_remote_${rname}")
        if [ "$path" = "" ]; then 
            echo ";; no path found for $current"
        elif [ "$remotePath" = "" ] ; then 
            echo ";; no remote found for $current"
        elif [ ! -d ./$path ]; then
            local remoteMod=$(add_user_to_remote $remotePath $UserAt)
            # echo $path
            # echo $remotePath
            # echo $UserAt
            # echo $remoteMod
            git clone ${remoteMod} ${path}
        else
            git --git-dir ${path}.git fetch
        fi
    done
    #echo done
}

checkout_version() {
    create_variables ${configfile} ''

    local ingredients=( "$@" )
    for current in "${ingredients[@]}"
    do
        # echo checkout $current
        local path=$(eval echo "\$${current}_path")
        local hash=$(eval echo "\$${current}_hash_${build}")

        if [ "$path" = "" ]; then 
            echo ";; no path found for $current"
        elif [ "$hash" = "" ]; then 
            echo ";; no hash found for $current"
        elif [ -d ./$path ]; then
            echo "${hash} - ${path}"
            local temp=`pwd`
            cd ${path} && git checkout ${hash}
            cd $temp

            #NOTE: This doesn't seem to work and I haven't dug into it much for why.
            # git --git-dir ./${path}.git checkout ${hash} -q
        else
            echo ";; path does not exist: $path"
        fi
    done
    #echo done
}

test_config() {
    create_variables ${configfile} ''
    
    local ingredients=( "$@" )
    for current in "${ingredients[@]}"
    do
        # TODO: Kind of a weak test; add more than just echoing a few of these
        echo testing $current
        if [ ! -z $(eval echo "\$${current}_path") ] ; then
            local path=$(eval echo "\$${current}_path")
            echo $path
        fi
        if [ ! -z $(eval echo "\$${current}_hash_${build}") ] ; then
            local hash=$(eval echo "\$${current}_hash_${build}")
            echo $hash
        fi
        if [ ! -z $(eval echo "\$${current}_remote_${rname}") ] ; then
            local remote=$(eval echo "\$${current}_remote_${rname}")
            if [ ! "$UserAt" = "" ] ; then
                local remoteMod=$(add_user_to_remote $remote $UserAt)
                echo $remoteMod
            else
                echo $remote
            fi

            local foo=https://foo/
            local bar=$(eval echo "\$${current}_remote_${rname}")
            local glux=${bar##*/}
            local remotePath=${foo:-$bar}${foo+$glux}
            echo $remotePath
        fi
    done
    #echo done
}

source ${hardmake}lib/yaml.sh

if [ "$configfile" = "" ]; then
    echo "No configfile."
    exit 1
elif [ "$ingredients" = "" ]; then
    echo "No dependencies."
    exit 1
elif [ "$mode" = "clone" ]; then
    clone_dependencies $ingredients
elif [ "$mode" = "checkout" ]; then
    checkout_version $ingredients
elif [ "$mode" = "remotes" ]; then
    add_remotes $ingredients
else
    test_config $ingredients
fi

exit
